package network;


import utils.Closeables;
import utils.Logger;

import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.Selector;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

public abstract class AbstractAccepter implements Runnable, Closeable {
    private volatile Selector selector;
    //
    protected final CountDownLatch startupLatch = new CountDownLatch(1);
    //
    protected final CountDownLatch shutdownLatch = new CountDownLatch(1);
    //是否存活
    protected final AtomicBoolean alive = new AtomicBoolean(false);

    final Logger logger = Logger.getLogger(getClass());

    /**
     * @return the selector
     * 双重检查锁
     */
    public Selector getSelector() {
        if (selector == null) {
            //对类进行加锁，加锁后需要在判断是否为空
           synchronized (AbstractAccepter.class){
               if(selector == null){
                   try {
                       selector = Selector.open();
                   } catch (IOException e) {
                       throw new RuntimeException(e);
                   }
               }
           }
        }
        return selector;
    }

    protected void closeSelector() {
        Closeables.closeQuietly(selector);
    }

    @Override
    public void close() throws IOException {
        //设置为不存活
        alive.set(false);
        selector.wakeup();
        try {
            shutdownLatch.await();
        } catch (InterruptedException e) {
            logger.error(e);
        }
    }

    //用CountDownLatch来保证Accepter在主线程继续往下执行前run()起来
    protected void startupComplete() {
        alive.set(true);
        startupLatch.countDown();
    }

    protected void shutdownComplete() {
        shutdownLatch.countDown();
    }
    protected boolean isRunning() {
        return alive.get();
    }

    public void awaitStartup() throws InterruptedException {
        startupLatch.await();
    }
}
